package io.persimmon.core.module.schedule;

import io.persimmon.core.exception.PersimmonExceptionFactory;
import io.persimmon.core.util.ThreadUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.Callable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class MultipleScheduleTask {
    private List<SingleScheduleImpl> scheduleTaskList;
    private int index = 0;

    public MultipleScheduleTask(List<SingleScheduleImpl> scheduleTaskList) {
        if (CollectionUtils.isEmpty(scheduleTaskList)) {
            throw PersimmonExceptionFactory.create("scheduleTaskList can not empty");
        }
        this.scheduleTaskList = scheduleTaskList;
    }


    public void submitDelayTask(Duration duration, Runnable runnable) {
        scheduleTaskList.get(index++ % scheduleTaskList.size()).submitDelayTask(duration, runnable);
    }


    public void submitTimingTask(Duration duration, Callable<Duration> runnable) {
        scheduleTaskList.get(index++ % scheduleTaskList.size()).submitTimingTask(duration, runnable);
    }

    public void submitTimingTask(Duration duration, int parallelThreadCount, Callable<Duration> runnable) {
        int min = Math.max(parallelThreadCount, this.scheduleTaskList.size());
        long wait = Math.max(duration.toMillis() / parallelThreadCount, 0);
        for (int i = 0; i < min; i++) {
            this.submitTimingTask(duration, runnable);
            if (wait > 0) {
                ThreadUtil.sleep(wait);
            }
        }
    }


    public void stop() {
        this.scheduleTaskList.forEach(SingleScheduleImpl::stop);
    }


}
